<template>
  <div class="grid">
    <div class="row" v-for="(item,index) in gridArr" :key="index" >
      <div :class="['col',val.color]" v-for="val in item" :key="val.id" >{{val.x}},{{val.y}}</div>
    </div>
    <button @click="leftBlock">点击左移</button>
    <button @click="downBlock">点击下移</button>
    <button @click="rightBlock">点击右移</button>
    <button @click="startTime">开始游戏</button>
    <button @click="transformation">变换</button>
  </div>
</template>

<script>
import {transformationBlock} from '@/utils/const'
export default {
  data () {
    return {
      row: 18, // 游戏区方块行
      col: 10, // 游戏区方块列

      footerArr: [{x: 0, y: 0, color: 'c1'}, {x: 0, y: 1, color: 'c1'}, {x: 0, y: 2, color: 'c1'}, {x: 1, y: 1, color: 'c1'}],
      currentDynamicBlock: [], // 当前下落的的方块
      gridArr: [], // 游戏区方块二位数二维数组
      gridArrFormat: [], // 游戏区方块一维数组
      taskInterval: null, // 用于清除定时
      index: Math.floor(Math.random() * 4), // Math.floor(Math.random() * 4), // Math.floor(Math.random() * 4)
      graphicalArr: [],
      defaultTransformationIndex: 0
    }
  },
  created () {
    this.graphicalArr = this.index === 0 ? transformationBlock(4, 0) : transformationBlock(5, 1)
    this.initGrid()
  },
  methods: {
    // 绘制游戏区方块
    initGrid () {
      let row = new Array(this.row).fill('')
      let col = new Array(this.col).fill('')
      let grid = []
      row.forEach((val, y) => {
        col.forEach((el, x) => {
          grid.push({x, y, color: 'initColor', id: `${x}${y}`})
        })
      })

      this.gridArrFormat = grid

      this.initCurrentBlock()
      // this.gridArrFormat = this.ergodicArrColouring(grid, this.currentDynamicBlock, 'init')
      // this.gridArr = this.twoDimenArrayGetArr(grid)
    },
    // 初始化一个当前下落的方块
    initCurrentBlock () {
      console.log('9999999999999999')
      let isTouchFoot = this.isTouchFooter(this.currentDynamicBlock, 'bottom', 'y', this.row - 1)
      console.log(isTouchFoot)
      this.graphicalArr = this.index === 0 ? transformationBlock(4, 0) : transformationBlock(5, 1)
      console.log(this.graphicalArr[this.index][0])
      this.currentDynamicBlock = this.graphicalArr[this.index][0]
      this.axisByIndex(this.index)
      this.gridArrFormat = this.ergodicArrColouring(this.gridArrFormat, this.currentDynamicBlock, 'init')
      console.log(this.twoDimenArrayGetArr(this.gridArrFormat))
      this.gridArr = this.twoDimenArrayGetArr(this.gridArrFormat)
    },
    // 开始游戏
    startTime () {
      // this.index = Math.floor(Math.random() * 4)
      this.initCurrentBlock()
      this.taskInterval = setInterval(() => { this.moveOperation('bottom', 'y', this.row - 1) }, 1000)
      // this.taskInterval = setTimeout(() => { this.moveOperation('bottom', 'y', this.row - 1) }, 1000)
    },
    // 变换
    transformation () {
      this.axisByIndex(this.index)
      let defaultIndex = this.defaultTransformationIndex

      let transformationArr = this.graphicalArr[this.index]
      this.gridArrFormat = this.ergodicArrColouring(this.gridArrFormat, transformationArr[defaultIndex], 'remove', 'transformation')
      if (defaultIndex >= transformationArr.length - 1) {
        defaultIndex = 0
      } else {
        defaultIndex = defaultIndex + 1
      }
      this.defaultTransformationIndex = defaultIndex
      this.currentDynamicBlock = transformationArr[defaultIndex]
      this.gridArrFormat = this.ergodicArrColouring(this.gridArrFormat, transformationArr[defaultIndex], 'add')
    },
    // 根据index判断初始化传入矩阵的值
    axisByIndex (index) {
      console.log(this.currentDynamicBlock)
      if (index === 0) {
        let XVal = Array.from(new Set(this.currentDynamicBlock.map(item => item.x)))
        let YVal = Array.from(new Set(this.currentDynamicBlock.map(item => item.y)))
        let centerX = XVal.reduce((a, b) => b < a ? b : a)
        let centerY = YVal.reduce((a, b) => b < a ? b : a)
        console.log(centerX, centerY)
        console.log(this.currentDynamicBlock)
        console.log(transformationBlock(centerX, centerY))
        this.graphicalArr = transformationBlock(centerX, centerY)
      } else {
        let XVal = Array.from(new Set(this.currentDynamicBlock.map(item => item.x)))
        let YVal = Array.from(new Set(this.currentDynamicBlock.map(item => item.y)))
        let centerX = XVal.length === 3 ? XVal.sort()[XVal.length - 2] : XVal.reduce((a, b) => b > a ? b : a)
        let centerY = YVal.length === 3 ? YVal.sort()[YVal.length - 2] : YVal.reduce((a, b) => b > a ? b : a)
        console.log(centerX, centerY)
        this.graphicalArr = transformationBlock(centerX, centerY)
      }
    },

    downBlock () {
      this.moveOperation('bottom', 'y', this.row - 1)
    },
    leftBlock () {
      this.moveOperation('left', 'x', 0)
    },
    rightBlock () {
      this.moveOperation('right', 'x', this.col - 1)
    },
    // 一维数组转二维数组
    twoDimenArrayGetArr (arr) {
      let twoDimenArr = []
      arr.forEach((val, index) => {
        const page = Math.floor(index / this.col)
        if (!twoDimenArr[page]) { // 判断是否存在
          twoDimenArr[page] = []
        }
        twoDimenArr[page].push(val)
      })
      return twoDimenArr
    },
    // 遍历数组填色或者去色
    ergodicArrColouring (val, currentArr, tag, direction) {
      let arr = val
      arr.forEach(el => {
        currentArr.forEach(val => {
          if (tag === 'add') {
            if (el.x === val.x && el.y === val.y) {
              el.x = val.x
              el.y = val.y
              el.color = val.color
            }
          } else if (tag === 'remove') {
            if (el.x === val.x + 1 && el.y === val.y && direction === 'left') {
              el.color = 'initColor'
            }
            if (el.x === val.x - 1 && el.y === val.y && direction === 'right') {
              el.color = 'initColor'
            }
            if (el.y === val.y - 1 && el.x === val.x && direction === 'bottom') {
              el.color = 'initColor'
            }
            if (el.y === val.y && el.x === val.x && direction === 'transformation') {
              // debugger
              el.color = 'initColor'
            }
          } else if (tag === 'init') {
            if (el.x === val.x && el.y === val.y) {
              el.x = val.x
              el.y = val.y
              el.color = val.color
            }
          }
        })
      })
      return arr
    },
    // 判断是否触底
    isTouchFooter (currentDynamicBlock, direction, field, limit, gridArrFormat) {
      return this.isTouchFootCount(currentDynamicBlock, limit, direction, field)
    },
    // 判断每步移动计算触底方法
    isTouchFootCount (currentDynamicBlock, limit, direction, field) {
      console.log(limit, direction, field)
      let arr = currentDynamicBlock.map(item => item[field])// 取出当前移动方向轴的值
      let gridArrFormat = this.gridArrFormat
      let currentDynamicBlockFormat = currentDynamicBlock
      let result = []
      let XArr = []
      let condition = []
      // let condition2 = []
      let XVal = Array.from(new Set(currentDynamicBlockFormat.map(item => item[field === 'x' ? 'y' : 'x'])))// 去除当前移动方向轴另一轴值并且去重
      // 遍历当前移动模块，把所有字段都放进一个二维数组
      XVal.forEach((val, index) => {
        currentDynamicBlockFormat.forEach(el => {
          if (val === el[field === 'x' ? 'y' : 'x']) {
            if (!XArr[index]) XArr[index] = []
            XArr[index].push(el)
          }
        })
      })
      // 进行遍历，找到移动方向轴上的最大值，如果是左移，找到最小值
      XArr.forEach(element => {
        result.push(direction === 'left' ? element.reduce((a, b) => b[field] < a[field] ? b : a) : element.reduce((a, b) => b[field] > a[field] ? b : a))
      })
      // 条件1，根据方向不同，找出移动方向下一个值有没有填色或者有没有放置模块
      result.forEach(el => {
        let val = null
        if (direction === 'bottom') {
          val = gridArrFormat.find(val => val && val.x === el.x && val[field] === el[field] + 1)
        } else if (direction === 'left') {
          val = gridArrFormat.find(val => val && val[field] === el[field] - 1 && val.y === el.y)
        } else {
          val = gridArrFormat.find(val => val && val[field] === el[field] + 1 && val.y === el.y)
        }
        condition.push(val)
      })
      // debugger
      // console.log(condition)
      // 条件2 是否超过移动方向的限制，如果是x轴左移，不能小于零，其他方向不能超过最大值
      let condition1 = direction === 'left' ? arr.filter(item => item === limit).length > 0 : arr.filter(item => item >= limit).length > 0
      let condition2 = condition.filter(item => item && item.color && item.color !== 'initColor').length > 0
      let condition3 = Array.from(new Set(currentDynamicBlockFormat.map(item => item[field])))
      // console.log(condition3, '======')
      // console.log(condition3.length > 0 ? condition3.reduce((a, b) => b > a ? a : b) : 100)
      // 只要满足上述任何一个条件，则返回true，警告触底
      return [condition2 || condition1, condition3.length > 0 ? condition3.reduce((a, b) => b > a ? a : b) : 100]
    },
    // 置空当前行
    clearCol (index) {
      let result = []
      let gridArr = this.gridArr

      let arr = gridArr.slice(0, index + 1)

      for (let i = arr.length - 1; i >= 0; i--) {
        if (i === 0) {
          arr[i] = arr[i]
        } else {
          arr[i] = arr[i - 1].map(item => {
            return {
              color: item.color,
              id: item.x + '' + i,
              x: item.x,
              y: i
            }
          })
        }
      }
      if (index === gridArr.length - 1) {
        console.log(1)
        console.log(arr)
        result = arr
      } else {
        console.log(2)
        console.log([...arr, ...this.gridArr.slice(index + 1)])
        result = [...arr, ...this.gridArr.slice(index + 1)]
      }

      this.gridArrFormat = result.flat()
      this.gridArr = this.twoDimenArrayGetArr(result.flat())
    },
    // 每个方向移动操作
    moveOperation (direction, field, limit) {
      let currentDynamicBlock = this.currentDynamicBlock
      let gridArrFormat = this.gridArrFormat
      let isTouchFoot = this.isTouchFooter(currentDynamicBlock, direction, field, limit, gridArrFormat) || false
      // debugger
      if (isTouchFoot[0]) {
        console.log(this.gridArr)
        this.gridArr.forEach((val, index) => {
          let a = val.filter(item => item.color !== 'initColor')
          if (a.length === this.col) {
            a.forEach(el => {
              el.color = 'initColor'
            })
            this.clearCol(index)
          }
        })
        // debugger
        console.log(this.gridArr)
        if (direction === 'bottom') {
          if (isTouchFoot[1] === 0) {
            alert(`游戏结束了`)
            clearInterval(this.taskInterval)
            // this.startTime()
          } else {
            // alert(`触${direction}了`)
            this.index = Math.floor(Math.random() * 4)
            clearInterval(this.taskInterval)
            this.startTime()
          }
          return true
        } else {
          alert(`触${direction}了`)
          clearInterval(this.taskInterval)
          return true
        }
      } else {
        if (direction === 'right' || direction === 'bottom') {
          currentDynamicBlock.forEach(val => {
            val[field] = val[field] + 1
          })
        } else {
          currentDynamicBlock.forEach(val => {
            val[field] = val[field] - 1
          })
        }
        this.currentDynamicBlock = currentDynamicBlock
        gridArrFormat = this.ergodicArrColouring(gridArrFormat, currentDynamicBlock, 'remove', direction)
        gridArrFormat = this.ergodicArrColouring(gridArrFormat, currentDynamicBlock, 'add')
        this.gridArrFormat = gridArrFormat
        this.gridArr = this.twoDimenArrayGetArr(gridArrFormat)
      }
    }
  }
}
</script>

<style lang="scss"  scoped>
.grid{
  width: 800px;
  height: 1200px;
  color:#fff;
  display: inline-block;
  margin: 0 auto;
  .row{
    width: 400px;
    height: 40px;
    line-height: 40px;
    margin: 0 auto;
    display: flex;
    justify-content: flex-start;
    // border-right: 1px #5e5e5e solid;
    border-left:2px #5e5e5e solid;
    .col{
      width: 40px;
      height: 100%;
      border-right:2px #5e5e5e solid;
      border-bottom:2px #5e5e5e solid;
    }
  }
  .borderLeft{
    border-left:1px #f00 solid;
  }
  .c0{
    background: #c20000;
  }
  .c1{
    background: #71ad47;
  }
  .c2{
    background: #00999a;
  }
  .c3{
    background: #e67d3a;
  }
  .c4{
    background: #599bd5;
  }
}
</style>
